package preorder

import (
    "time"
	"strconv"
	"encoding/json"
	"dhfshop/controllers/base"
	"dhfshop/domain/preorder"
	"dhfshop/models/preorder"
	"dhfshop/models/member"
	"dhfshop/models/isv"
	"dhfshop/domain/im"
	"dhfshop/models/consts"
	"github.com/astaxie/beego"
	"dhfshop/domain/nsqproc"
	"github.com/astaxie/beego/validation"
)

type PreOrderController struct {
	base.BaseController
}

func (this *PreOrderController) List() {
	query,_, fields, order_by, offset, limit, err := this.GetQueryPara()
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	curRoleId := this.Ctx.Input.GetData("curRoleId").(int) 
	companyId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	//beego.Debug("curRoleId:",curRoleId)
	//beego.Debug("companyId:", companyId)
	//beego.Debug("curUserId", curUserId)
	if curRoleId == 1 {
		query["member_id"] = strconv.FormatInt(curUserId, 10)
		query["partner_id"] = strconv.FormatInt(companyId, 10)
	}else if curRoleId == 2 {
	    query["partner_id"] = strconv.FormatInt(companyId, 10)
	}else{
	
	}
	l, cnt, err := preorder.GetAllPreOrders(query, fields, order_by, offset, limit)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	r := struct {
		TotalCount int64                `json:"total_count"`
		PreOrder   []*preorder.PreOrder `json:"preorders"`
	}{TotalCount: cnt, PreOrder: l}
	this.Data["json"] = r
	this.ServeJSON()
}

// 只能买家角色预约，后台预约的话，需要重写一个接口
func (this *PreOrderController) Post() {
	var v preorder.PreOrder
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.ResItemId, "res_item_id")
	valid.Required(v.PeriodsId, "periods_id")
	valid.Required(v.TimeslotsId, "timeslots_id")
	valid.Required(v.IsPayDeposit, "is_pay_deposit")
	valid.Required(v.Note, "note")
	valid.Required(v.FormId, "form_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	v.PartnerId = int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	/*
	curRoleId := this.Ctx.Input.GetData("curRoleId").(int) 
	if curRoleId == 1 {
		curAppId := this.Ctx.Input.GetData("curAppId").(string)		
	} else {
	    
	}
	*/
	v.MemberId = int64(curUserId)
	if ok := preorder.ExistPreOrder(v.ResItemId,v.PeriodsId,v.MemberId); ok {
	    this.ServeError("同一个项目同一个用户同一天只能预约一次")
		return 
	}
	resItem, err := preorder.GetResItemById(v.ResItemId)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.StoreId = resItem.StoreId
	v.ResItem = resItem
	period, err := preorder.GetPeriodsById(v.PeriodsId)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.Periods = period
	timeslot, err := preorder.GetTimeslotsById(v.TimeslotsId)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	curNo, err := preorderlayer.ReduceSource(timeslot)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.SourceAt = period.SourceAt
	v.Start = timeslot.Start 
	v.End = timeslot.End
	v.OrderSeq = curNo
	v.Timeslots = timeslot
	beego.Debug("OrderSeq:", v.OrderSeq)
	id, err := preorder.AddPreOrder(&v)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	v.PreOrderId = int64(id)
	members, err := member.GetMemberById(v.MemberId)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	if custAccount, err := isv.GetCustAccountByAppId(members.AppId); err == nil {
		if templateId, err := imlayer.GetTemplateId(v.PartnerId,members.AppId,"AT0104"); err == nil {
		    page := ""
			sourceAtStr := v.Periods.SourceAt.Format(consts.DATE_FORMAT)
		    err = imlayer.ReserveSuccessTempMsg(custAccount.AccessToken,page,members.OpenID,templateId,v.FormId,resItem.Name,sourceAtStr)
			if err != nil {
				beego.Debug("ReserveSuccessTempMsg:", err.Error())
			}
		}
	}
	types := "ReminderArrived"
	ttlSeconds := v.SourceAt.Unix() - time.Now().UTC().Unix() + 24*3600
	body := struct {
		PreOrderId int64 `json:"pre_order_id"`
	}{PreOrderId: v.PreOrderId}
	if callBackData, err := json.Marshal(&body); err == nil {
		if err = nsqproc.RpcAddTimerTask(types, string(callBackData), int(ttlSeconds)); err != nil {
		    beego.Debug("RpcAddTimerTask:", err.Error())
		}
	}
	rsp := struct {
		PreOrderId  int64     `json:"pre_order_id"`
		Modified        time.Time `json:"modified"`
	}{PreOrderId: id, Modified: time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *PreOrderController) Update() {
	var v preorder.PreOrder
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.PreOrderId, "pre_order_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	if v.ResItemId > 0 {
	    resItem, err := preorder.GetResItemById(v.ResItemId)
		if err != nil {
			this.ServeError(err.Error())
			return 
		}
		v.ResItem = resItem
	}
	updateFields, err := this.GetUpdateFields(v, "", "form", []string{"pre_order_id"})
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	if v.PeriodsId > 0 {
	    period, err := preorder.GetPeriodsById(v.PeriodsId)
		if err != nil {
			this.ServeError(err.Error())
			return 
		}
		v.Periods = period
		v.SourceAt = period.SourceAt
		updateFields = append(updateFields, "source_at")
	}
	if v.TimeslotsId > 0 {
	    timeslot, err := preorder.GetTimeslotsById(v.TimeslotsId)
		if err != nil {
			this.ServeError(err.Error())
			return 
		}
		v.Timeslots = timeslot
		v.Start = timeslot.Start 
	    v.End = timeslot.End
		updateFields = append(updateFields, "start", "end")
	}
	
	if len(updateFields) > 0 {
		err := preorder.UpdatePreOrderById(&v, updateFields...)
		if err != nil {
			this.ServeError(err.Error())
			return
		}
	}
	rsp := struct {
		PreOrderId  int64     `json:"pre_order_id"`
		Modified    time.Time `json:"modified"`
	}{PreOrderId: v.PreOrderId, Modified: time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *PreOrderController) Delete() {
	var v preorder.PreOrder
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.PreOrderId, "pre_order_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	err := preorder.DeletePreOrder(v.PreOrderId)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	r := struct {
		PreOrderId  int64       `json:"pre_order_id"`
		Modified    time.Time   `json:"modified"`
	}{PreOrderId: v.PreOrderId, Modified: time.Now().UTC()}
	this.Data["json"] = r
	this.ServeJSON()
}

